/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.module.reporting.common; import java.util.Comparator; import org.apache.commons.beanutils.PropertyUtils; /** * A comparator that can compare 2 objects based on a particular nested property value */ @SuppressWarnings("rawtypes") public class BeanPropertyComparator implements Comparator { private String sortSpecification; /** * Constructor */ public BeanPropertyComparator(String sortSpecification) { this.sortSpecification = sortSpecification; } /** * @see Comparator#compare(Object, Object) */ @SuppressWarnings({ "unchecked" }) @Override public int compare(Object left, Object right) { try { for (String token : sortSpecification.split(",")) { String[] values = token.trim().split(" "); String property = values[0]; boolean sortAsc = (values.length == 1 || !values[1].equalsIgnoreCase("desc")); Object valueLeft = PropertyUtils.getNestedProperty(left, property); Object valueRight = PropertyUtils.getNestedProperty(right, property); //We put NULLs at the bottom. if (valueLeft == null) return 1; if (valueRight == null) return -1; if (!valueLeft.equals(valueRight)) { int ret = ((Comparable)valueLeft).compareTo(valueRight); if (!sortAsc) { ret = (ret == 1 ? -1 : 1); } return ret; } //else values are equal. Try next sort property } } catch (Exception ex) { throw new IllegalArgumentException("Unable to compare " + left + " and " + right + " using sort specification: " + sortSpecification); } return 0; } }